home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
telecomm
/
t100.zoo
/
vt100.c
< prev
Wrap
C/C++ Source or Header
|
1991-09-21
|
19KB
|
983 lines
#define DEBUG
/*
* vt100.c - emulates a vt100 using vt52 codes when possible
*
* this code handles an escape sequence only. on entry, the ESC has
* already been read from AUX:. it writes all output to CON: via bios.
*
* this compiles (and runs :-) with gcc 1.40 and mint libraries, PL 10.
* it should also work with "normal" gcc libraries.
*/
#ifndef lint
static char *rcsid_vt100_c = "$Id: vt100.c,v 1.0 1991/09/12 20:32:56 rosenkra Exp $";
#endif
/*
* $Log: vt100.c,v $
* Revision 1.0 1991/09/12 20:32:56 rosenkra
* Initial revision
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <osbind.h>
#include "t100.h"
/*
* macro to get a char from AUX. we check status some number of times.
* if no char available, we may have a hosed connection or host screwed
* up. otherwise, if char available, get it. use BIOS...
*/
#define GET_NEXT_CHAR \
{ \
long counter; \
for (counter = 1000; counter; counter--) {\
if (Bconstat (AUX)) break; \
} \
if (counter == 0) goto no_char_avail; \
c = (int) Bconin (AUX); \
}
/*
* default value if none specified. if not 0, be careful!
*/
#define VAL_DEFAULT 0
/*
* modes, etc...
*/
extern int bold; /* OFF 1m */
extern int underline; /* OFF 4m */
extern int blinking; /* OFF 5m */
extern int reverse; /* OFF 7m */
extern int wrap; /* ON (set) */
extern int video; /* 0=normal (reset) */
extern int repeat; /* ON (set) */
extern int curskey; /* OFF (reset) */
extern int keypad; /* 0=normal (reset) */
extern int colwidth; /* 0=80 (reset), 1=132 */
extern int smooth; /* OFF (reset) */
extern int origmode; /* 0=normal (reset) */
/*------------------------------*/
/* vt100 */
/*------------------------------*/
void vt100 ()
{
/*
* emulate vt100. upon entry, we got a ESC char from AUX. only the
* ESC was read so far.
*
* note: in order to report things back to the host, we must know
* things like baud rate, parity, etc. these are not in the termcap,
* however, so don't sweat it for now. we also can't report postion.
*
* we do not do character generators (g0 and g1).
*
* we do not do LEDs.
*
* here is the basic logic:
*
* we got an ESC already from AUX.
*
* get_next_char.
* if (current_char == >,=,8,7,or M)
* handle.
* done.
* else if (current_char == [)
* get_next_char.
* if (current_char == ?)
* get_next_char. it should be 1-8. save val.
* get_next_char. it should be h or l.
* handle.
* done.
* else if (current_char == number)
* read all of number. convert and save.
* get_next_char.
* else
* val1 = 0 (or 1)
* if (current_char == ;)
* get_next_char.
* if (current_char == number)
* read all of number. convert and save.
* get_next_char.
* else
* val2 = 0 (or 1)
* switch (current_char)
* H or f
* r
* R
* else
* switch (current_char)
* A
* B
* C
* D
* H
* J
* K
* L
* M
* P
* g
* h
* l
* m
* n
* x
* @
* else
* error?
*
*/
/*
here are likely codes to be seen. xxx is optional, 0, 1, or 2 chars:
\E [ xxx J
\E [ xxx K
\E [ xxx ; xxx H position cursor
\E [ xxx H special case of position cursor
\E [ xxx ; xxx r
\E [ xxx C cursor right
\E [ xxx D cursor left
\E [ xxx B cursor down
\E [ xxx A cursor up
\E 8
\E 7
\E M
\E [ ? 1 l cursor key mode reset
\E [ ? 1 h set
\E [ ? 3 l col width reset (to 80)
\E [ ? 4 l
\E [ ? 5 l
\E [ ? 7 h
\E [ ? 8 h auto repeat mode set
\E >
\E =
\E [ 1 m
\E [ 4 m
\E [ 5 m
\E [ 7 m
\E [ 0 m
\E [ m
this is a real vt100 termcap with equiv vt52 codes:
vt100 vt52 desc
:cd=\E[J: :\EJ: clear display after cursor
:ce=\E[K: :\EK: clear to end of line
:cl=\E[;H\E[2J: :\EH\EJ: home cursor, clear screen
:cm=\E[%i%d;%dH: :\EY%+ %+ : move to row #1 and col #2
:cs=\E[%i%d;%dr: --- change scrolling region to rows #1 to #2
:ho=\E[H: :\EH: move cursor home
:is=\E[1;24r\E[24;1H: :\Ev\Ee: initialization string (wrapon, curs vis)
:nd=\E[C: :\EC: non-destructive space (move right)
:rc=\E8: :\Ek: restore cursor to position saved by sc
:sc=\E7: :\Ej: save absolute cursor position
:sr=\EM: :\EI: scroll reverse one line
:up=\E[A: :\EA: move cursor up
:rs=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h: reset to sane modes
:ke=\E[?1l\E>: --- turn keypad off, if possible
:ks=\E[?1h\E=: --- turn keypad on, if possible
:mb=\E[5m: --- turn on blinking attribute
:md=\E[1m: --- turn on bold
:me=\E[m: :\Eq: turn off all attributes
:mr=\E[7m: :\Ep: turn on reverse video
:se=\E[m: :\Eq: end standout (reverse) mode
:so=\E[7m: :\Ep: begin standout (reverse) mode
:ue=\E[m: --- end underline mode
:us=\E[4m: --- begin underline mode
*/
register int c;
register int val1;
register int val2;
int row;
int col;
int i;
/*
* this is first char after an ESC.
*/
GET_NEXT_CHAR;
/*
* what is it?
*/
switch (c)
{
case 'Z': /* terminal ID */
/* this is obsolete. use ESC [ c */
return;
break; /*NOTREACHED*/
case 'c': /* reset to initial state */
vt100_reset ();
return;
break; /*NOTREACHED*/
case 'H': /* set tab at current position */
return;
break; /*NOTREACHED*/
case 'D': /* index */
Bconout (CON, (int) 27);
Bconout (CON, (int) 'B');
return;
break; /*NOTREACHED*/
case 'M': /* scroll reverse one line */
Bconout (CON, (int) 27);
Bconout (CON, (int) 'I');
return;
break; /*NOTREACHED*/
case 'E': /* next line */
Bconout (CON, (int) 13);
Bconout (CON, (int) 27);
Bconout (CON, (int) 'B');
return;
break; /*NOTREACHED*/
case '>': /* reset keypad (normal) */
keypad = 0;
return;
break; /*NOTREACHED*/
case '=': /* set keypad (application) */
keypad = 1;
return;
break; /*NOTREACHED*/
case '8': /* restore cursor to saved loc */
Bconout (CON, (int) 27);
Bconout (CON, (int) 'k');
return;
break; /*NOTREACHED*/
case '7': /* save cursor location */
Bconout (CON, (int) 27);
Bconout (CON, (int) 'j');
return;
break; /*NOTREACHED*/
case '[':
/*
* get next one...
*/
GET_NEXT_CHAR;
if (c == '?')
{
/*
* next char SHOULD be a number...
*/
GET_NEXT_CHAR;
if ((c >= '0') && (c <= '9'))
{
/*
* get all of number. store as int val1.
*/
val1 = 0;
do
{
val1 = (10 * val1) + (c - '0');
GET_NEXT_CHAR;
} while ((c >= '0') && (c <= '9'));
/*
* what was last char? (one causing do/while
* to stop)
*/
if (c == 'l')
{
switch (val1)
{
case 1: /* reset cursor key */
curskey = 0;
return;
break; /*NOTREACHED*/
case 2: /* change mode */
/*
* this may not be portable
*/
return;
break; /*NOTREACHED*/
case 3: /* reset col width */
colwidth = 0;
return;
break; /*NOTREACHED*/
case 4: /* reset smooth scroll*/
smooth = 0;
return;
break; /*NOTREACHED*/
case 5: /* reset screen mode */
/*
* normal video. bg is color
* 0. fg depends on rez.
* black is low intens (0),
* white is high (777).
*/
switch (Getrez ())
{
case 0:
Setcolor (0, 0x777);
Setcolor (15, 0);
break;
case 1:
Setcolor (0, 0x777);
Setcolor (3, 0);
break;
case 2:
Setcolor (0, 0x777);
Setcolor (1, 0);
break;
}
video = 0;
return; /*NOTREACHED*/
break;